package net.zui.comp;

import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.InputMethodEvent;
import java.awt.event.InputMethodListener;
import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.font.TextHitInfo;
import java.awt.font.TextLayout;
import java.awt.im.InputMethodRequests;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.AttributedCharacterIterator.Attribute;

import net.zui.Option;
import net.zui.entity.ZTextRender;
import net.zui.enume.TextAlign;
import net.zui.inter.IGroup;
import net.zui.util.UComm;
import net.zui.util.UDraw;

public class ZText extends ZRect implements InputMethodListener,InputMethodRequests{
	// 插入符定位器，用以记载游标所在位置
	private TextHitInfo caret = null;
	// 用户已输入数据缓存
	private StringBuffer messageText = new StringBuffer();
	// 已输入信息的字符构成数据
	private AttributedCharacterIterator composedText;
	// 已输入信息的字符串构成数据
	private AttributedString composedTextString;
	// 空的输入法信息
	private static final Attribute[] IM_ATTRIBUTES = { TextAttribute.INPUT_METHOD_HIGHLIGHT };
	protected ZTextRender ztext=new ZTextRender("");
	// 空的字符信息迭代器
	private static final AttributedCharacterIterator EMPTY_TEXT = (new AttributedString("")).getIterator();
	// 已输入文本定位器
	private Point textOrigin;
	// 文本布局器，用以限定输入后显示的具体位置
	private transient TextLayout textLayout = null;
	// 判定是否验证输入法布局器
	private transient boolean validTextLayout = false;

	public ZText(String id, IGroup frame, int x, int y, int width, int height,String text) {
		this(id, frame, x, y, width, height,0,text);
	}

	public ZText(String id, IGroup frame, int x, int y, int width, int height, int index,String text) {
		super(id, frame, x, y, width, height, index,Option.getBackColor());
		ztext.setText(text);
		messageText.append(text);
		group.getTop().addInputMethodListener(this);
		border=Option.getBorder();
		ztext.setAlign(TextAlign.left);
		textOrigin = UDraw.alignString(ztext, width, height, Option.padding);
	}
	
	@Override
	public boolean hasFocus() {
		return true;
	}

	@Override
	protected void draw(Graphics2D g) {
		super.draw(g);
		TextLayout textLayout = getTextLayout();
		if (textLayout != null) {
			textLayout.draw((Graphics2D) g, textOrigin.x, textOrigin.y);
		}
		Rectangle rectangle = getCaretRectangle();
		if (group.getManager().getFocus()==this && rectangle != null) {
			g.setXORMode(backColor);
			g.fillRect(rectangle.x, rectangle.y, 1, rectangle.height);
			g.setPaintMode();
		}
	}

	@Override
	public Rectangle getTextLocation(TextHitInfo offset) {
		Rectangle rectangle;
		if (offset == null) {
			rectangle = getCaretRectangle();
		} else {
			TextHitInfo globalOffset = offset
					.getOffsetHit(getCommittedTextLength());
			rectangle = getCaretRectangle(globalOffset);
		}
		Point location = group.getTop().getLocationOnScreen();
		rectangle.translate(location.x, location.y);
		return rectangle;
	}
	
	/**
	 * 返回对应插入点的矩形选框
	 * 
	 * @return
	 */
	public Rectangle getCaretRectangle() {
		TextHitInfo caret = getCaret();
		if (caret == null) {
			return null;
		}
		return getCaretRectangle(caret);
	}
	
	/**
	 * 返回当前插入符所在位置
	 * 
	 * @return
	 */
	public TextHitInfo getCaret() {
		if (composedText == null) {
			return TextHitInfo.trailing(messageText.length() - 1);
		} else if (caret == null) {
			return null;
		} else {
			return caret.getOffsetHit(getCommittedTextLength());
		}
	}
	
	/**
	 * 返回对应插入点的矩形选框
	 * 
	 * @param caret
	 * @return
	 */
	public Rectangle getCaretRectangle(TextHitInfo caret) {
		TextLayout textLayout = getTextLayout();
		int caretLocation;
		if (textLayout != null) {
			caretLocation = Math.round(textLayout.getCaretInfo(caret)[0]);
		} else {
			caretLocation = 0;
		}
		FontMetrics metrics = getGraphics().getFontMetrics();
		UComm.info(this.getClass(), "textOrigin.y:",textOrigin.y," metrics.getAscent():",metrics.getAscent());
		return new Rectangle(textOrigin.x + caretLocation, textOrigin.y
				- metrics.getAscent(), 0, metrics.getAscent()
				+ metrics.getDescent());
	}

	@Override
	public TextHitInfo getLocationOffset(int x, int y) {
		Point location = group.getTop().getLocationOnScreen();
		Point textOrigin = getTextOrigin();
		x -= location.x + textOrigin.x;
		y -= location.y + textOrigin.y;
		TextLayout textLayout = getTextLayout();
		if (textLayout != null && textLayout.getBounds().contains(x, y)) {
			return textLayout.hitTestChar(x, y).getOffsetHit(
					-getCommittedTextLength());
		} else {
			return null;
		}
	}
	
	/**
	 * 返回当前文本布局器
	 * 
	 * @return
	 */
	public synchronized TextLayout getTextLayout() {
		if (!validTextLayout) {
			textLayout = null;
			AttributedCharacterIterator text = getDisplayText();
			if (text.getEndIndex() > text.getBeginIndex()) {
				FontRenderContext context = ((Graphics2D) getGraphics())
						.getFontRenderContext();
				textLayout = new TextLayout(text, context);
			}
		}
		validTextLayout = true;
		return textLayout;
	}
	
	public Graphics getGraphics() {
        return group.getTop().getCanvas().getGraphics();
    }
	
	/**
	 * 返回用于显示的输入信息集
	 * 
	 * @return
	 */
	public AttributedCharacterIterator getDisplayText() {
		if (composedText == null) {
			return getDisplayTextToAttributedCharacterIterator();
		} else {
			return EMPTY_TEXT;
		}
	}
	
	public AttributedCharacterIterator getDisplayTextToAttributedCharacterIterator() {
		AttributedString string = new AttributedString(messageText.toString());
		if (messageText.length() > 0) {
			string.addAttribute(TextAttribute.FONT, ztext.getFont());
		}
		return string.getIterator();
	}

	@Override
	public int getInsertPositionOffset() {
		return getCommittedTextLength();
	}

	@Override
	public AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex, Attribute[] attributes) {
		return getMessageText(beginIndex, endIndex);
	}
	
	/**
	 * 将messageText转化为指定范围内的字符信息迭代器
	 * 
	 * @param beginIndex
	 * @param endIndex
	 * @return
	 */
	public AttributedCharacterIterator getMessageText(int beginIndex,
			int endIndex) {
		AttributedString string = new AttributedString(messageText.toString());
		return string.getIterator(null, beginIndex, endIndex);
	}

	@Override
	public int getCommittedTextLength() {
		return messageText.length();
	}

	@Override
	public AttributedCharacterIterator cancelLatestCommittedText(Attribute[] attributes) {
		return null;
	}

	@Override
	public AttributedCharacterIterator getSelectedText(Attribute[] attributes) {
		return EMPTY_TEXT;
	}

	@Override
	public void inputMethodTextChanged(InputMethodEvent e) {
		int committedCharacterCount = e.getCommittedCharacterCount();
		AttributedCharacterIterator text = e.getText();
		composedText = null;
		char c;
		if (text != null) {
			// 需要复制的字符长度
			int toCopy = committedCharacterCount;
			c = text.first();
			while (toCopy-- > 0) {
				insertCharacter(c);
				c = text.next();
			}
			if (text.getEndIndex()
					- (text.getBeginIndex() + committedCharacterCount) > 0) {
				composedTextString = new AttributedString(text, text
						.getBeginIndex()
						+ committedCharacterCount, text.getEndIndex(),
						IM_ATTRIBUTES);
				composedTextString.addAttribute(TextAttribute.FONT, ztext.getFont());
				composedText = composedTextString.getIterator();
			}
		}
		e.consume();
		caret = e.getCaret();
		System.out.println(789);
	}
	
	/**
	 * 插入指定字符串
	 * 
	 * @param c
	 */
	public void insertCharacter(char c) {
		messageText.append(c);
		//invalidateTextLayout();
	}

	@Override
	public void caretPositionChanged(InputMethodEvent event) {
		caret = event.getCaret();
		event.consume();
		System.out.println(456);
		//repaint();
	}
	
	/**
	 * 返回文本绘制点
	 * 
	 * @return
	 */
	public Point getTextOrigin() {
		return textOrigin;
	}
}
